home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / installboot / installboot.c < prev    next >
C/C++ Source or Header  |  1992-01-09  |  7KB  |  253 lines

  1. /* 
  2.  * installboot.c --
  3.  *
  4.  *    Copy a boot program to the correct place on the disk.
  5.  *
  6.  * Copyright 1986 Regents of the University of California
  7.  * All rights reserved.
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software and its documentation for any purpose and without
  10.  * fee is hereby granted, provided that the above copyright
  11.  * notice appear in all copies.  The University of California
  12.  * makes no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without
  14.  * express or implied warranty.
  15.  */
  16.  
  17. #ifndef lint
  18. static char rcsid[] = "$Header: /sprite/src/admin/installboot/RCS/installboot.c,v 1.8 92/01/08 22:54:48 jhh Exp $ SPRITE (Berkeley)";
  19. #endif
  20.  
  21. #include <sprite.h>
  22. #include <option.h>
  23. #include <disk.h>
  24.  
  25. #include <stdio.h>
  26. #include <errno.h>
  27. #include <sys/file.h>
  28.  
  29. /*
  30.  * Settable via the command line.
  31.  */
  32. Boolean unixStyleBootFile = FALSE;
  33. Boolean keepHeader = FALSE;
  34.  
  35. /*
  36.  * The following are used to go from a command line like
  37.  * bootInstall -dev rsd0
  38.  * to /dev/rsd0a     - for the partition that has the disk label
  39.  * and to /dev/rsd0b    - for the partition to format.
  40.  */
  41. char *deviceName;        /* Set to "rsd0" or "rxy1", etc. */
  42. char defaultFirstPartName[] = "a";
  43. char *firstPartName = defaultFirstPartName;
  44. char devDirectory[] = "/dev/";
  45.  
  46. Option optionArray[] = {
  47.     {OPT_STRING, "dev", (Address)&deviceName,
  48.     "Required: Name of device, eg \"rsd0\" or \"rxy1\""},
  49.     {OPT_STRING, "part", (Address)&firstPartName,
  50.     "Optional: Partition ID: (a, b, c, d, e, f, g)"},
  51.     {OPT_TRUE, "noStrip", (Address)&keepHeader,
  52.     "Do not strip off the a.out header (sun4c)\n",},
  53.     {OPT_TRUE, "u", (Address)&unixStyleBootFile,
  54.     "The boot file has no a.out header (unix style)\n",},
  55. };
  56. int numOptions = sizeof(optionArray) / sizeof(Option);
  57.  
  58. /*
  59.  * Forward Declarations.
  60.  */
  61. ReturnStatus InstallBoot();
  62. ReturnStatus DecHeader(), SunHeader();
  63.  
  64.  
  65. /*
  66.  *----------------------------------------------------------------------
  67.  *
  68.  * main --
  69.  *
  70.  *    Create the required file names from the command line
  71.  *    arguments.  Then open the first partition on the disk
  72.  *    and copy the boot program there.
  73.  *
  74.  * Results:
  75.  *    None.
  76.  *
  77.  * Side effects:
  78.  *    Calls InstallBoot
  79.  *
  80.  *----------------------------------------------------------------------
  81.  */
  82. main(argc, argv)
  83.     int argc;
  84.     char *argv[];
  85. {
  86.     ReturnStatus status;    /* status of system calls */
  87.     int diskFID;        /* File ID for first parition on the disk */
  88.     int bootFID;        /* File ID for partiton to format */
  89.     char firstPartitionName[64];
  90.     char *bootFile;
  91.  
  92.     argc = Opt_Parse(argc, argv, optionArray, numOptions);
  93.  
  94.     if (deviceName == (char *)0) {
  95.     printf("Specify device name with -dev option\n");
  96.     status = FAILURE;
  97.     } else if (argc < 2) {
  98.     printf("Specify boot program after options\n");
  99.     status = FAILURE;
  100.     } else {
  101.     bootFile = argv[1];
  102.     status = SUCCESS;
  103.     }
  104.     if (status != SUCCESS) {
  105.     exit(FAILURE);
  106.     }
  107.     /*
  108.      * Gen up the name of the first partition on the disk.
  109.      */
  110.     (void)strcpy(firstPartitionName, devDirectory);    /* eg. /dev/ */
  111.     (void)strcat(firstPartitionName, deviceName);    /* eg. /dev/rxy0 */
  112.     (void)strcat(firstPartitionName, firstPartName);    /* eg. /dev/rxy0a */
  113.  
  114.     diskFID = open(firstPartitionName, O_RDWR, 0);
  115.     if (diskFID < 0) {
  116.     fprintf(stderr, "Can't open \"%s\": %s\n",
  117.                   firstPartitionName, strerror(errno));
  118.     exit(status);
  119.     }
  120.     bootFID = open(bootFile, O_RDONLY, 0);
  121.     if (bootFID < 0) {
  122.     fprintf(stderr, "Can't open boot file \"%s\": %s\n",
  123.                   bootFile, strerror(errno));
  124.     exit(status);
  125.     }
  126.     status = InstallBoot(diskFID, bootFID);
  127.  
  128.     exit(status);
  129. }
  130.  
  131. /*
  132.  *----------------------------------------------------------------------
  133.  *
  134.  * InstallBoot --
  135.  *
  136.  *    Write a boot program to the boot sectors of the disk.
  137.  *
  138.  * Results:
  139.  *    An error code.
  140.  *
  141.  * Side effects:
  142.  *    Write all over the disk partition.
  143.  *
  144.  *----------------------------------------------------------------------
  145.  */
  146. ReturnStatus
  147. InstallBoot(diskFID, bootFID)
  148.     int diskFID;    /* Handle on the first partition of the disk */
  149.     int bootFID;    /* Handle on the boot program */
  150. {
  151.     ReturnStatus status;
  152.     register int numBlocks;
  153. #if 1    
  154.     Disk_Label *diskInfoPtr;
  155. #else    
  156.     Disk_Info  *diskInfoPtr;
  157. #endif    
  158.     Dec_DiskBoot    decBootInfo;
  159.     int bytesRead;
  160.     Address sector;
  161.     int sectorIndex;
  162.     Address loadAddr;
  163.     Address execAddr;
  164.     int    length;
  165.     int    headerSize;
  166.     int toRead;
  167.     int decDisk = 0;    /* 1 if this is a Dec disk. */
  168.  
  169.     /*
  170.      * Read the copy of the super block at the beginning of the partition
  171.      * to find out basic disk geometry and where to write the boot program.
  172.      */
  173. #if 1
  174.     if ((diskInfoPtr = Disk_ReadLabel(diskFID)) == NULL) {
  175.     return FAILURE;
  176.     }
  177. #else    
  178.     diskInfoPtr = Disk_ReadDiskInfo(diskFID, 0);
  179.     if (diskInfoPtr == (Disk_Info *)0) {
  180.     return(FAILURE);
  181.     }
  182. #endif    
  183.     if (Disk_ReadDecLabel(diskFID) != (Dec_DiskLabel *)0) {
  184.     decDisk++;
  185.     }
  186.  
  187.     if ((headerSize = SunHeader(bootFID, &loadAddr, &execAddr, &length)) < 0) {
  188.     if (DecHeader(bootFID, &loadAddr, &execAddr, &length) != SUCCESS) {
  189.         printf("Need impure text format (OMAGIC) file\n");
  190.         return FAILURE;
  191.     }
  192.     }
  193.  
  194.     if (keepHeader) {
  195.     lseek(bootFID, 0L, 0);
  196.     length += headerSize;
  197.     }
  198.  
  199.     /*
  200.      * Write the boot information block.
  201.      */
  202.     if (decDisk) {
  203.     diskInfoPtr->bootSector = DEC_BOOT_SECTOR + 1;
  204.     decBootInfo.magic = DEC_BOOT_MAGIC;
  205.     decBootInfo.mode = 0;
  206.     decBootInfo.loadAddr = (int) loadAddr;
  207.     decBootInfo.execAddr = (int) execAddr;
  208.     decBootInfo.map[0].numBlocks = diskInfoPtr->numBootSectors;
  209.     decBootInfo.map[0].startBlock = diskInfoPtr->bootSector;
  210.     decBootInfo.map[1].numBlocks = 0;
  211.     status = Disk_SectorWrite(diskFID, DEC_BOOT_SECTOR, 1, &decBootInfo);
  212.     if (status < 0) {
  213.         fprintf(stderr, "Sector write %d failed: ", DEC_BOOT_SECTOR);
  214.         perror("");
  215.         return(errno);
  216.     }
  217.     }
  218.     /*
  219.      * Write the remaining code to the correct place on the disk.
  220.      */
  221.     sector = (Address)malloc(DEV_BYTES_PER_SECTOR);
  222.     for (sectorIndex=0 ; sectorIndex < diskInfoPtr->numBootSectors && length>0;
  223.              sectorIndex++) {
  224.     bzero(sector, DEV_BYTES_PER_SECTOR);
  225.     toRead = length < DEV_BYTES_PER_SECTOR ? length :
  226.         DEV_BYTES_PER_SECTOR;
  227.     bytesRead = read(bootFID, sector, toRead);
  228.     if (bytesRead < toRead) {
  229.         perror("Boot file read failed");
  230.         return(status);
  231.     }
  232.     if (bytesRead > 0) {
  233.         length -= bytesRead;
  234.         status = Disk_SectorWrite(diskFID,
  235.                  diskInfoPtr->bootSector + sectorIndex,
  236.                  1, sector);
  237.         if (status < 0) {
  238.         fprintf(stderr, "Sector write %d failed: ", sectorIndex);
  239.         perror("");
  240.         return(errno);
  241.         }
  242.     } else {
  243.         sectorIndex++;
  244.         break;
  245.     }
  246.     }
  247.     printf("Wrote %d sectors\n", sectorIndex);
  248.     if (length > 0) {
  249.     printf("Warning: didn't reach end of boot program!\n");
  250.     }
  251.     return(SUCCESS);
  252. }
  253.